package com.example.guardian.home;

import static android.widget.ListView.*;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.guardian.R;
import com.example.guardian.myadapter.TCase;
import com.example.guardian.myadapter.T_CaseAdapter;
import com.example.guardian.myadapter.result_adapter;
import com.example.guardian.network.PostKeywords;
import com.speech.setting.IatSettings;
import com.speech.util.JsonParser;
import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.RecognizerListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechRecognizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;
import com.yinglan.scrolllayout.ScrollLayout;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;

import okhttp3.Call;
import okhttp3.Response;

public class VoiceActivity extends AppCompatActivity {

    private static String TAG = VoiceActivity.class.getSimpleName();

    // 语音听写对象
    private com.iflytek.cloud.SpeechRecognizer mIat;
    // 语音听写UI
    private RecognizerDialog mIatDialog;
    // 用HashMap存储听写结果
    private HashMap<String, String> mIatResults = new LinkedHashMap<>();

    private Toast mToast;
    private SharedPreferences mSharedPreferences;
    // 引擎类型
    private String mEngineType = SpeechConstant.TYPE_CLOUD;

    private String language = "zh_cn";
    private int selectedNum = 0;
    private String[] languageEntries;
    private String[] languageValues;
    private String resultType = "json";

    private StringBuffer buffer = new StringBuffer();

    public static String audio_path;
    public static EditText Voice_Text;


    private static Object sVmRuntime;
    private static Method setHiddenApiExemptions;

    //private ListView ListView;

    private List<TCase> tVCaseList = new ArrayList<>();
    private List<ArrayList<String>> kind_list = new ArrayList<ArrayList<String>>();

    private T_CaseAdapter TV_adapter = new T_CaseAdapter(VoiceActivity.this,tVCaseList);

    private result_adapter result_adapter;

    private String kind;
    private String rate;
    private String formula;
    private String target;
    private String prevent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home_voice);
        Context appContext = getApplicationContext();
        TextView kind_name = findViewById(R.id.kind_name);
        TextView kind_rate = findViewById(R.id.kind_rate);
        TextView kind_target = findViewById(R.id.target_people);
        TextView fomularr = findViewById(R.id.formula);
        TextView prev = findViewById(R.id.prevent);
        ScrollLayout scrollLayout = findViewById(R.id.scroll_down_layout);
        // 初始化识别无UI识别对象
        SpeechUtility.createUtility(VoiceActivity.this, SpeechConstant.APPID+ "=8d6a27b7");

        // 使用SpeechRecognizer对象，可根据回调消息自定义界面；



        mIat = SpeechRecognizer.createRecognizer(VoiceActivity.this, mInitListener);

        // 初始化听写Dialog，如果只使用有UI听写功能，无需创建SpeechRecognizer
        // 使用UI听写功能，请根据sdk文件目录下的notice.txt,放置布局文件和图片资源
        mIatDialog = new RecognizerDialog(VoiceActivity.this, mInitListener);

        mSharedPreferences = getSharedPreferences(IatSettings.PREFER_NAME,
                Activity.MODE_PRIVATE);


        Button open_file = (Button) findViewById(R.id.voice_file);
        Button beign_speak = (Button) findViewById(R.id.voice_speak);
        Button start_recognition = (Button) findViewById(R.id.voice_search);
        Voice_Text = (EditText) findViewById(R.id.voice_content);
        
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null){
            actionBar.hide();
        }
        Button back_button = findViewById(R.id.voice_back_btn);

        back_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                VoiceActivity.this.finish();
            }
        });


        //this.ListView = (ListView) findViewById(R.id.Call_List_view);

        GridView result = (GridView) findViewById(R.id.CR_gridview) ;

        GridView listview = (GridView) findViewById(R.id.Call_List_view) ;
        result_adapter = new result_adapter(kind_list,VoiceActivity.this);

        listview.setAdapter(TV_adapter);
        //ListView item的展开事件
        TV_adapter.setOnItemSpreadClickListener(new T_CaseAdapter.onItemSpreadListener() {
            @Override
            public void onSpreadClick(int i) {

                TCase t_item = tVCaseList.get(i);
                AlertDialog.Builder builder = new AlertDialog.Builder(VoiceActivity.this);
                builder.setTitle(t_item.getCase_name());
                builder.setMessage(t_item.getCase_content());
                builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //Toast.makeText(MainActivity.this, "??",Toast.LENGTH_SHORT).show();
                    }
                });
                builder.show();
            }
        });

        fomularr.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AlertDialog.Builder builder = new AlertDialog.Builder(VoiceActivity.this);
                builder.setTitle("典型套路");
                builder.setMessage(formula);
                builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //Toast.makeText(MainActivity.this, "??",Toast.LENGTH_SHORT).show();
                    }
                });
                builder.show();

            }
        });

        prev.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AlertDialog.Builder builder = new AlertDialog.Builder(VoiceActivity.this);
                builder.setTitle("防范措施");
                builder.setMessage(prevent);
                builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //Toast.makeText(MainActivity.this, "??",Toast.LENGTH_SHORT).show();
                    }
                });
                builder.show();

            }
        });

        open_file.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                ActivityCompat.requestPermissions(VoiceActivity.this,
                        new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        1);
                Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, VoiceActivity.ActivityRequestCode.SHOW_MAP_DEPOT);

            }
        });

        beign_speak.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                ActivityCompat.requestPermissions(VoiceActivity.this,
                        new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        1);
                speak();
            }

        });

        start_recognition.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                tVCaseList.clear();
                kind_list.clear();
                String input_words = Voice_Text.getText().toString();
                if(input_words.isEmpty()){
                    Toast.makeText(getApplicationContext(),"请您上传诈骗电话音频或说话描述",Toast.LENGTH_SHORT).show();
                }else{
                    PostKeywords.sendOkHttpRequest("http://124.220.154.99:5000/words_select",input_words,new okhttp3.Callback(){
                        @RequiresApi(api = Build.VERSION_CODES.N)
                        @Override
                        public void onResponse(Call call, Response response) throws IOException {
                            //得到服务器返回的具体内容
                            String responseData = response.body().string();
                            parseDiffJson(responseData);
                            showResponse(responseData);
                        }
                        @Override
                        public void onFailure(Call call, IOException e) {
                            //在这里对异常数据进行处理
                        }
                        private void showResponse(final String response) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    if(response.isEmpty()){
                                        Toast.makeText(getApplicationContext(),"请您上传诈骗电话音频或说话描述",Toast.LENGTH_SHORT).show();
                                    }else {
                                        if (kind_list.isEmpty()) {
                                            AlertDialog.Builder builder = new AlertDialog.Builder(VoiceActivity.this);
                                            builder.setTitle("暂时安全");
                                            //builder.setMessage("暂时安全");
                                            builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                                @Override
                                                public void onClick(DialogInterface dialog, int which) {
                                                    //Toast.makeText(MainActivity.this, "??",Toast.LENGTH_SHORT).show();
                                                }
                                            });
                                            builder.show();

                                            listview.setAdapter(TV_adapter);
                                            result.setAdapter(result_adapter);
                                            setHeight.setGridViewHeight(appContext, result);
                                            setHeight.setGridViewHeight(appContext,listview);
                                            kind_name.setText("暂时安全");
                                            kind_rate.setText("");
                                            kind_target.setText("");
                                            fomularr.setText("");
                                            prev.setText("");
                                            scrollLayout.setToExit();
                                        } else {

                                            result.setAdapter(result_adapter);
                                            listview.setAdapter(TV_adapter);
                                            setHeight.setGridViewHeight(appContext, result);
                                            setHeight.setGridViewHeight(appContext, listview);
                                            kind_name.setText(kind);
                                            kind_rate.setText(rate);
                                            kind_target.setText(target);
                                            fomularr.setText(formula);
                                            prev.setText(prevent);
                                            scrollLayout.setToOpen();
                                        }
                                    }
                                }
                            });
                        }
                    });
                }
            }
        });
    }

    private void initTCase(String Kind_name,String Case_name,String Case_content) {
        TCase tcase = new TCase(Kind_name,Case_name, Case_content);
        tVCaseList.add(tcase);

    }
    //解析JSON
    @RequiresApi(api = Build.VERSION_CODES.N)
    private void parseDiffJson(String json) {
        try {
            JSONArray jsonArray = new JSONArray(json);
            //List PicNameList = new ArrayList();
            List official_case_name_lst = new ArrayList();
            JSONObject jsonObject_relative = (JSONObject) jsonArray.get(0);
            kind = jsonObject_relative.getString("m.name");
            rate = jsonObject_relative.getString("probability");
            target = jsonObject_relative.getString("m.feature");
            formula = jsonObject_relative.getString("m.routine");
            prevent = jsonObject_relative.getString("m.measure");
            for (int i = 1; i < jsonArray.length(); i++) {
                JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                //取出word
                String word = jsonObject.getString("word");
                //取出case列表
                JSONArray cases = jsonObject.getJSONArray("case");
                //取出kind列表
                JSONArray kinds = jsonObject.getJSONArray("kind");
                //Log.e("Json_word", word);
                //对case列表进行操作
                for (int c = 0; c < cases.length(); c++) {
                    JSONObject jsonObject_case = (JSONObject) cases.get(c);
                    String pics_name = jsonObject_case.getString("name");
                    //PicNameList.add(pics_name);
                    //Log.e("Json_pic_name", pics_name);
                }
                //PicNameList = GetTopN.topNFrequent(PicNameList,6);
                //Log.e("pic", PicNameList.toString());
                //对kind列表进行操作
                for (int k = 0; k < kinds.length(); k++) {
                    JSONObject jsonObject_kind = (JSONObject) kinds.get(k);
                    //取出kind的name
                    String kind_name = jsonObject_kind.getString("name");
                    //取出kind的measure
                    String kind_measure = jsonObject_kind.getString("measure");
                    //取出kind的feature
                    String kind_feature = jsonObject_kind.getString("feature");
                    List small_kind_List = new ArrayList<String>();
                    small_kind_List.add(kind_name);
                    small_kind_List.add(kind_feature);
                    if(kind_list.contains(kind_name) == false) {
                        kind_list.add((ArrayList<String>) small_kind_List);
                    }
                    //取出official_case列表
                    JSONArray official_case = jsonObject_kind.getJSONArray("official_case");
                    /*Log.e("Json_kind_name", kind_name);
                    Log.e("Json_kind_measure", kind_measure);
                    Log.e("Json_kind_feature", kind_feature);*/
                    for (int o = 0; o < official_case.length(); o++) {
                        JSONObject jsonObject_official_case = (JSONObject) official_case.get(o);
                        //取出官方案例的标题
                        String official_case_name = jsonObject_official_case.getString("m.name");
                        //取出官方案例的内容
                        String official_case_details = jsonObject_official_case.getString("m.details");
                        /*Log.e("Json_kind_name", kind_name);
                        Log.e("Json_official_case_name", official_case_name);
                        Log.e("Json_case_details", official_case_details);*/
                        if(official_case_name_lst.contains(official_case_name) == false) {
                        initTCase(kind_name,official_case_name,official_case_details);
                            official_case_name_lst.add(official_case_name);
                        }
                    }
                }
            }
            Log.e("pic",kind_list.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public interface ActivityRequestCode {
        public static final int SHOW_MAP_DEPOT = 1; //显示Android自带音频，用于上传
    }

    ;

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (data != null) {
            if (requestCode == ActivityRequestCode.SHOW_MAP_DEPOT
                    && resultCode == Activity.RESULT_OK)
                show(data);
        }
    }

    ;

    public void show(Intent data) {
        Uri selectedAudio = data.getData();
        String[] audioColumns = {MediaStore.Audio.Media.DATA};

        Cursor cursor = getContentResolver().query
                (selectedAudio, audioColumns, null, null, null);
        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(audioColumns[0]);

        String picturePath = cursor.getString(columnIndex);

        String filePath =
                cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
        cursor.close();


        String pic_path = filePath; // 保存所添加的音频的路径

        audio_path = pic_path;

        Log.d("pic_path", pic_path);
        System.out.println("filePath=" + pic_path);
        //System.out.println("filePath=" + picturePath);

        executeStream(pic_path);

    }




    int ret = 0; // 函数调用返回值

    /**
     * 初始化监听器。
     */
    private InitListener mInitListener = new InitListener() {

        @Override
        public void onInit(int code) {
            Log.d(TAG, "SpeechRecognizer init() code = " + code);
            if (code != ErrorCode.SUCCESS) {
                showTip("初始化失败，错误码：" + code + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
            }
        }
    };



    /**
     * 听写监听器。
     */
    private RecognizerListener mRecognizerListener = new RecognizerListener() {

        @Override
        public void onBeginOfSpeech() {
            // 此回调表示：sdk内部录音机已经准备好了，用户可以开始语音输入
            showTip("开始说话");
        }

        @Override
        public void onError(SpeechError error) {
            // Tips：
            // 错误码：10118(您没有说话)，可能是录音机权限被禁，需要提示用户打开应用的录音权限。
            Log.d(TAG, "onError " + error.getPlainDescription(true));
            showTip(error.getPlainDescription(true));

        }

        @Override
        public void onEndOfSpeech() {
            // 此回调表示：检测到了语音的尾端点，已经进入识别过程，不再接受语音输入
            showTip("结束说话");
        }

        @Override
        public void onResult(RecognizerResult results, boolean isLast) {
            Log.d(TAG, results.getResultString());
            if (isLast) {
                Log.d(TAG, "onResult 结束");
            }
            if (resultType.equals("json")) {
                printResult(results);
                return;
            }
            if (resultType.equals("plain")) {
                buffer.append(results.getResultString());
                Voice_Text.setText(buffer.toString());
                Voice_Text.setSelection(Voice_Text.length());
            }
        }

        @Override
        public void onVolumeChanged(int volume, byte[] data) {
            showTip("当前正在说话，音量大小 = " + volume + " 返回音频数据 = " + data.length);
        }

        @Override
        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
            // 以下代码用于获取与云端的会话id，当业务出错时将会话id提供给技术支持人员，可用于查询会话日志，定位出错原因
            // 若使用本地能力，会话id为null
            //	if (SpeechEvent.EVENT_SESSION_ID == eventType) {
            //		String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
            //		Log.d(TAG, "session id =" + sid);
            //	}
        }
    };

    /**
     * 显示结果
     */
    private void printResult(RecognizerResult results) {
        String text = JsonParser.parseIatResult(results.getResultString());
        String sn = null;
        // 读取json结果中的sn字段
        try {
            JSONObject resultJson = new JSONObject(results.getResultString());
            sn = resultJson.optString("sn");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        mIatResults.put(sn, text);

        StringBuffer resultBuffer = new StringBuffer();
        for (String key : mIatResults.keySet()) {
            resultBuffer.append(mIatResults.get(key));
        }
        Voice_Text.setText(resultBuffer.toString());
        Voice_Text.setSelection(Voice_Text.length());
    }

    /**
     * 听写UI监听器
     */
    private RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() {
        // 返回结果
        public void onResult(RecognizerResult results, boolean isLast) {
            printResult(results);
        }

        // 识别回调错误
        public void onError(SpeechError error) {
            showTip(error.getPlainDescription(true));
        }

    };


    private void showTip(final String str) {
        if (mToast != null) {
            mToast.cancel();
        }
        mToast = Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT);
        mToast.show();
    }

    /**
     * 参数设置
     *
     * @return
     */
    public void setParam() {
        // 清空参数
        mIat.setParameter(SpeechConstant.PARAMS, null);
        // 设置听写引擎
        mIat.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
        // 设置返回结果格式
        mIat.setParameter(SpeechConstant.RESULT_TYPE, resultType);

        if (language.equals("zh_cn")) {
            String lag = mSharedPreferences.getString("iat_language_preference",
                    "mandarin");
            // 设置语言
            Log.e(TAG, "language = " + language);
            mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
            // 设置语言区域
            mIat.setParameter(SpeechConstant.ACCENT, lag);
        } else {
            mIat.setParameter(SpeechConstant.LANGUAGE, language);
        }
        Log.e(TAG, "last language:" + mIat.getParameter(SpeechConstant.LANGUAGE));

        //此处用于设置dialog中不显示错误码信息
        //mIat.setParameter("view_tips_plain","false");

        // 设置语音前端点:静音超时时间，即用户多长时间不说话则当做超时处理
        mIat.setParameter(SpeechConstant.VAD_BOS, mSharedPreferences.getString("iat_vadbos_preference", "4000"));

        // 设置语音后端点:后端点静音检测时间，即用户停止说话多长时间内即认为不再输入， 自动停止录音
        mIat.setParameter(SpeechConstant.VAD_EOS, mSharedPreferences.getString("iat_vadeos_preference", "1000"));

        // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
        mIat.setParameter(SpeechConstant.ASR_PTT, mSharedPreferences.getString("iat_punc_preference", "1"));

        // 设置音频保存路径，保存音频格式支持pcm、wav.
        mIat.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
        mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH,
                getExternalFilesDir("msc").getAbsolutePath() + "/iat.wav");
    }

    /**
     * 执行在线听写
     */
    private void speak() {
        buffer.setLength(0);
        Voice_Text.setText(null);// 清空显示内容
        mIatResults.clear();
        // 设置参数
        setParam();
        mIatDialog.setListener(mRecognizerDialogListener);
        mIatDialog.show();
        showTip(getString(R.string.text_begin));

        // 显示听写对话框

    }


    /**
     * 执行音频流识别操作
     */
    private void executeStream(String path) {
        buffer.setLength(0);
        Voice_Text.setText(null);// 清空显示内容
        mIatResults.clear();
        // 设置参数


        setParam();
        // 设置音频来源为外部文件
        mIat.setParameter(SpeechConstant.AUDIO_SOURCE, "-2");
        mIat.setParameter(SpeechConstant.ASR_SOURCE_PATH, path);
        // 也可以像以下这样直接设置音频文件路径识别（要求设置文件在sdcard上的全路径）：
        // mIat.setParameter(SpeechConstant.AUDIO_SOURCE, "-2");
        // mIat.setParameter(SpeechConstant.ASR_SOURCE_PATH, "sdcard/XXX/XXX.pcm");
        ret = mIat.startListening(mRecognizerListener);
        if (ret != ErrorCode.SUCCESS) {
            showTip("识别失败,错误码：" + ret + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
            return;
        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mIat != null) {
            // 退出时释放连接
            mIat.cancel();
            mIat.destroy();
        }
    }
    private void identify() {

    }
}